home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / lpDaemon SRC / Common Sources / Utilities.C < prev   
Encoding:
Text File  |  1993-02-14  |  18.0 KB  |  611 lines  |  [TEXT/KAHL]

  1. /************************************************************************
  2.  *                                                                        *
  3.  *    Utilities.c                                                            *
  4.  *                                                                        *
  5.  *  Written by Casper Boon, August, 1992.                                *
  6.  *                                                                        *
  7.  *  These are a collection of routines taken from my library providing    *
  8.  *  useful and commonly used functions.                                    *
  9.  *                                                                        *
  10.  *    © 1992 Casper Boon.                                                    *
  11.  *                                                                        *
  12.  ************************************************************************/
  13.  
  14. void SetExtnsFolder(void);
  15. void SetPrefsFolder(void);
  16. void SetSystemFolder(void);
  17.  
  18. /************************************************************************
  19.  *                                                                         *
  20.  ************************************************************************/
  21.  
  22. /* dialutils.c */
  23.  
  24. /************************************************************************
  25.  *                                                                         *
  26.  * This is a dialog user item routine installed as the user item         *
  27.  * surrounding the default button in a dialog.                            *
  28.  *                                                                         *
  29.  ************************************************************************/
  30. pascal void DefaultFrame(DialogPtr dial, integer item)
  31. {
  32.     Handle        hand;
  33.     integer        type;
  34.     Rect        rect;
  35.  
  36.     GetDItem(dial, item, &type, &hand, &rect);
  37.     PenSize(2, 2);
  38.     FrameRoundRect(&rect, 16, 16);
  39.     PenNormal();
  40. }
  41.  
  42. /************************************************************************
  43.  *                                                                         *
  44.  * Install a user item routine the easy way.                            *
  45.  *                                                                         *
  46.  ************************************************************************/
  47. void InstallUserItem(DialogPtr dial, integer item, ProcPtr proc)
  48. {
  49.     Handle        hand;
  50.     integer        type;
  51.     Rect        rect;
  52.  
  53.     GetDItem(dial, item, &type, &hand, &rect);
  54.     type &= ~itemDisable;
  55.     if (type == userItem)
  56.         SetDItem(dial, item, type, (Handle)proc, &rect);
  57. }
  58.  
  59. /************************************************************************
  60.  *                                                                         *
  61.  * Extract the text from a dialog text item the easy way.                *
  62.  *                                                                         *
  63.  ************************************************************************/
  64. void GetDialText(DialogPtr dial, integer item, StringPtr text)
  65. {
  66.     Handle        hand;
  67.     integer        type;
  68.     Rect        rect;
  69.  
  70.     GetDItem(dial, item, &type, &hand, &rect);
  71.     type &= ~itemDisable;
  72.     if (type == statText || type == editText)
  73.         GetIText(hand, text);
  74.     else
  75.         text[0] = 0;
  76. }
  77.  
  78. /************************************************************************
  79.  *                                                                         *
  80.  * Set the text of a text item in a dialog                                *
  81.  *                                                                         *
  82.  ************************************************************************/
  83. void SetDialText(DialogPtr dial, integer item, StringPtr text)
  84. {
  85.     Handle        hand;
  86.     integer        type;
  87.     Rect        rect;
  88.  
  89.     GetDItem(dial, item, &type, &hand, &rect);
  90.     type &= ~itemDisable;
  91.     if (type == statText || type == editText)
  92.         SetIText(hand, text);
  93. }
  94.  
  95.  
  96. /************************************************************************
  97.  *                                                                         *
  98.  * Set the value of a dialog control.                                    *
  99.  *                                                                         *
  100.  ************************************************************************/
  101. void SetDialCtlVal(DialogPtr dial, integer item, integer value)
  102. {
  103.     Handle    hand;
  104.     integer type;
  105.     Rect    rect;
  106.  
  107.     GetDItem(dial, item, &type, &hand, &rect);
  108.     if (type & ctrlItem)
  109.         SetCtlValue((ControlHandle)hand, value);
  110. }
  111.  
  112.  
  113. /************************************************************************
  114.  *                                                                         *
  115.  * Get the value of a dialog control item                                *
  116.  *                                                                         *
  117.  ************************************************************************/
  118. integer GetDialCtlVal(DialogPtr dial, integer item)
  119. {
  120.     Handle    hand;
  121.     integer type;
  122.     Rect    rect;
  123.  
  124.     GetDItem(dial, item, &type, &hand, &rect);
  125.     if (type & ctrlItem)
  126.         return GetCtlValue((ControlHandle)hand);
  127.     return 0;
  128. }
  129.  
  130.  
  131. /************************************************************************
  132.  *                                                                         *
  133.  * Usually used for check boxes or radio buttons,  turn the control on    *
  134.  * when off or vice versa                                                *
  135.  *                                                                         *
  136.  ************************************************************************/
  137. void ToggleDialCtlVal(DialogPtr dial, integer item)
  138. {
  139.     Handle    hand;
  140.     integer type;
  141.     Rect    rect;
  142.  
  143.     GetDItem(dial, item, &type, &hand, &rect);
  144.     if (type & ctrlItem)
  145.         SetCtlValue((ControlHandle)hand, (GetCtlValue((ControlHandle)hand))?0:1);
  146. }
  147.  
  148. /************************************************************************
  149.  *                                                                         *
  150.  ************************************************************************/
  151. /* fileutils.c */
  152.  
  153. /************************************************************************
  154.  *                                                                         *
  155.  *  Display an error message when something goes wrong in the file        *
  156.  *  utilities.                                                              *
  157.  *                                                                         *
  158.  ************************************************************************/
  159. void FileError(StringPtr s, integer e)
  160. {
  161.     Str255        str;
  162.  
  163.     psprintf(str, "File System Error\015\015%p\015errNo %d", s, e);
  164.     ParamText(str, NIL, NIL, NIL);    /* tell dialog manager     */
  165.  
  166.     InternalAlert();
  167. }
  168.  
  169.  
  170. /************************************************************************
  171.  *                                                                        *
  172.  *  Set the default working directory.  Also sets the current directory    *
  173.  * for the standard file package.  (See tech note 80.)                    *
  174.  *                                                                        *
  175.  ************************************************************************/
  176. void SetWDir(integer wdRef, LongInt wdID, integer vol)
  177. {
  178.     SetVol(NIL, wdRef);        /* wd must be open            */
  179.     CurDirStore = wdID;        /* will be ignored by MFS    */
  180.     SFSaveDisk = vol;
  181. }
  182.  
  183.  
  184. /************************************************************************
  185.  *                                                                        *
  186.  * The complement to SetWDir above.                                        *
  187.  *                                                                        *
  188.  ************************************************************************/
  189. void GetWDir(integer *wdRef, LongInt *wdID, integer *vol)
  190. {
  191.     *wdID = CurDirStore;
  192.     *vol = SFSaveDisk;
  193.     GetVol(NIL, wdRef);
  194. }
  195.  
  196.  
  197. /************************************************************************
  198.  ************************************************************************/
  199. #include <Traps.h>
  200. #include <Folders.h>
  201. #include <GestaltEqu.h>
  202.  
  203. /************************************************************************
  204.  *                                                                        *
  205.  * Get the blessed folder information                                    *
  206.  *                                                                        *
  207.  ************************************************************************/
  208. void GetSystemFolder(integer *vRefNumP, LongInt *dirIDP, integer *sysVRefNum);
  209. void GetSystemFolder(integer *vRefNum, LongInt *dirID, integer *sysVRefNum)
  210. {
  211.     SysEnvRec info;
  212.     LongInt wdProcID;
  213.     
  214.     SysEnvirons(1, &info);
  215.     *sysVRefNum = info.sysVRefNum;
  216.     if (GetWDInfo(info.sysVRefNum, vRefNum, dirID, &wdProcID) != noErr)
  217.         {
  218.         log_printf("Failed to get system folder\n");
  219.         *vRefNum = 0;
  220.         *dirID = 0;
  221.         }
  222. }
  223.  
  224. Boolean TrapAvailable(LongWord trap);
  225.  
  226. /************************************************************************
  227.  *                                                                        *
  228.  * Set the current working directory to the Extensions folder.          *
  229.  *                                                                        *
  230.  ************************************************************************/
  231. void SetExtnsFolder()
  232. {
  233.     LongInt feature;
  234.     integer vRefNum, sysVRefNum, err;
  235.     LongInt dirID;
  236.     WDPBRec    wdpb;
  237.  
  238.     GetSystemFolder(&vRefNum, &dirID, &sysVRefNum);
  239.  
  240.     if (TrapAvailable(_GestaltDispatch) &&
  241.             Gestalt(gestaltFindFolderAttr, &feature) == noErr)
  242.         {
  243.         if (FindFolder(kOnSystemDisk, kExtensionFolderType,
  244.                         kDontCreateFolder, &vRefNum, &dirID) != noErr)
  245.             {
  246.             }
  247.         }
  248.  
  249.     ClearBytes((Ptr)(&wdpb), sizeof(wdpb));
  250.     wdpb.ioNamePtr = NIL;
  251.     wdpb.ioVRefNum = vRefNum;
  252.     wdpb.ioWDDirID = dirID;
  253.     if ( (err = PBHSetVol((HParmBlkPtr)&wdpb, FALSE)) != noErr )
  254.         FileError("\pHSetVol Error", err);
  255. }
  256.  
  257. /************************************************************************
  258.  *                                                                        *
  259.  * Set the current working directory to the Preferences folder.          *
  260.  *                                                                        *
  261.  ************************************************************************/
  262. void SetPrefsFolder()
  263. {
  264.     LongInt feature;
  265.     integer vRefNum, sysVRefNum, err;
  266.     LongInt dirID;
  267.     WDPBRec    wdpb;
  268.     
  269.     GetSystemFolder(&vRefNum, &dirID, &sysVRefNum);
  270.  
  271.     if (TrapAvailable(_GestaltDispatch) &&
  272.             Gestalt(gestaltFindFolderAttr, &feature) == noErr)
  273.         {
  274.         if (FindFolder(kOnSystemDisk, kPreferencesFolderType,
  275.                         kDontCreateFolder, &vRefNum, &dirID) != noErr)
  276.             {
  277.             }
  278.         }
  279.  
  280.     ClearBytes((Ptr)(&wdpb), sizeof(wdpb));
  281.     wdpb.ioNamePtr = NIL;
  282.     wdpb.ioVRefNum = vRefNum;
  283.     wdpb.ioWDDirID = dirID;
  284.     if ( (err = PBHSetVol((HParmBlkPtr)&wdpb, FALSE)) != noErr )
  285.         FileError("\pHSetVol Error", err);
  286. }
  287.  
  288. /************************************************************************
  289.  *                                                                        *
  290.  *  Sets the default working directory to be the system folder.  (See    *
  291.  * Tech notes 66, 67 and 77.)  If the name passed is the name of a        *
  292.  * folder this will open the folder and set the default directory to    *
  293.  * this folder and return TRUE. otherwise we return FALSE.                *
  294.  *                                                                        *
  295.  * Unlike the SetExtnsFolder and SetPrefsFolder above this routine also    *
  296.  * sets the standard file valiables to open here.                        *
  297.  *                                                                        *
  298.  ************************************************************************/
  299. integer SetToBlessedFolder(StringPtr aFoldName)
  300. {
  301.     HVolumeParam    myHPB;
  302.     HFileParam        myHFPB;
  303.     WDPBRec            myWDPB;
  304.     CInfoPBRec        myCIPB;
  305.     integer            vRef, wdRef,
  306.                     retVal = FALSE, osVal;
  307.     LongInt            wdID;
  308.  
  309.     ClearBytes((Ptr)(&myHPB), sizeof(myHPB));
  310.     ClearBytes((Ptr)(&myHFPB), sizeof(myHFPB));
  311.     ClearBytes((Ptr)(&myWDPB), sizeof(myWDPB));
  312.     ClearBytes((Ptr)(&myCIPB), sizeof(myCIPB));
  313.  
  314.     myHPB.ioNamePtr = NIL;
  315.     myHPB.ioVRefNum = BootDrive;
  316.     myHPB.ioVolIndex = 0;
  317.  
  318.     if (FSFCBLen > 0)
  319.         {
  320.         GetVRefNum(SysMap, &vRef);    /* which volume is system on    */
  321.         myHPB.ioVRefNum = vRef;
  322.  
  323.         if (osVal = PBHGetVInfo((HParmBlkPtr)&myHPB, FALSE) )
  324.             FileError("\pPBHGetVInfo", osVal);
  325.         wdID = myHPB.ioVFndrInfo[0];    /* the blessed folder ID    */
  326.  
  327.         myWDPB.ioNamePtr = NIL;
  328.         myWDPB.ioVRefNum = vRef;
  329.         myWDPB.ioWDProcID = 'ERIK';        /* created by the system    */
  330.         myWDPB.ioWDDirID = wdID;
  331.         if ( osVal = PBOpenWD(&myWDPB, FALSE) )    /* open the blessed folder    */
  332.             FileError("\pOpenBlssd", osVal);
  333.  
  334.                 /* this is then the refNum of the blessed folder    */
  335.         wdRef = myWDPB.ioVRefNum;
  336.  
  337.         if (aFoldName)                    /* were we given a name?    */
  338.             {
  339.             myCIPB.dirInfo.ioNamePtr = aFoldName;
  340.             myCIPB.dirInfo.ioVRefNum = wdRef;
  341.             myCIPB.dirInfo.ioFDirIndex = 0;
  342.             myCIPB.dirInfo.ioDrDirID = 0;
  343.  
  344.                             /* get info about object with this name */
  345.             if ( osVal = PBGetCatInfo(&myCIPB, FALSE) )
  346.                 {
  347.                 myHFPB.ioNamePtr = aFoldName;
  348.                 myHFPB.ioVRefNum = vRef;
  349.                 myHFPB.ioDirID = wdID;
  350.  
  351.                 if ( osVal = PBDirCreate((HParmBlkPtr)&myHFPB, FALSE) )
  352.                     {
  353.                     FileError("\pPBDirCreate", osVal);
  354.                     return FALSE;
  355.                     }
  356.                 if ( PBGetCatInfo(&myCIPB, FALSE) )
  357.                     {
  358.                     FileError("\pPBGetCatInfo", osVal);
  359.                     retVal = FALSE;    /* no such name, creation must have failed */
  360.                     }
  361.                 }
  362.             if (myCIPB.dirInfo.ioFlAttrib & 0x10)
  363.                 {                                /* it's a directory    */
  364.                 PBClose((ParmBlkPtr)&myWDPB, FALSE);    /* close blessed folder */
  365.  
  366.                 wdID = myCIPB.dirInfo.ioDrDirID;
  367.                 myWDPB.ioNamePtr = NIL;
  368.                 myWDPB.ioVRefNum = vRef;
  369.                 myWDPB.ioWDProcID = 'ERIK';    /*     */
  370.                 myWDPB.ioWDDirID = wdID;
  371.                 if ( osVal = PBOpenWD(&myWDPB, FALSE) )
  372.                     FileError("\pPBOpenWD", osVal);
  373.         
  374.                 wdRef = myWDPB.ioVRefNum;
  375.                 retVal = TRUE;
  376.                 }
  377.             }
  378.         }
  379.     else PBGetVInfo((ParmBlkPtr)&myHPB, FALSE);      /* for "flat" volumes    */
  380.  
  381.     SetWDir(wdRef, wdID, -vRef);           /* set the default directory    */
  382.  
  383.     return retVal;
  384. }
  385.  
  386. /************************************************************************
  387.  *                                                                        *
  388.  * Seems to be missing from the high level file manager, a simple way    *
  389.  * to flush the file to disk.  This actually only flushes to the disc    *
  390.  * buffer and to ensure data integrity the volume must also be flushed    *
  391.  *                                                                        *
  392.  ************************************************************************/
  393. integer FSFlush(integer    fRef)
  394. {
  395.     HFileParam myHFPB;
  396.  
  397.     ClearBytes((Ptr)(&myHFPB), sizeof(myHFPB));
  398.  
  399.     myHFPB.ioFRefNum = fRef;
  400.     return PBFlushFile((ParmBlkPtr)&myHFPB, FALSE);
  401. }
  402.  
  403. /************************************************************************
  404.  *                                                                        *
  405.  * When reading files we often need only open it to read but FSOpen     *
  406.  * tries to open with write permission too and that may fail if the     *
  407.  * file has already been opened.  FSOpenRO opens the file as read only.    *
  408.  *                                                                        *
  409.  ************************************************************************/
  410. integer FSOpenRO(StringPtr name, integer vRef, integer *file)
  411. {
  412.     HFileParam myHFPB;
  413.     integer        err;
  414.  
  415.     ClearBytes((Ptr)(&myHFPB), sizeof(myHFPB));
  416.  
  417.     myHFPB.ioNamePtr = name;
  418.     myHFPB.ioVRefNum = vRef;
  419.     myHFPB.filler1 = fsRdPerm;        /* actually the ioPermssn byte */
  420.     if ( !(err = PBOpen((ParmBlkPtr)&myHFPB, FALSE) ) )
  421.         *file = myHFPB.ioFRefNum;
  422.     return err;
  423. }
  424.  
  425. /************************************************************************
  426.  *                                                                        *
  427.  * Given a file that is already open for which we only have the name    *
  428.  * and volume reference FSGetFRef returns the file reference.  This is    *
  429.  * used by the spooler when trying to remove a file.  If the delete        *
  430.  * fails the file is probably open so we find the reference number and    *
  431.  * close the file then try deleting it.                                    *
  432.  *                                                                        *
  433.  ************************************************************************/
  434. integer FSGetFRef(StringPtr name, integer vRef, integer *fRef)
  435. {
  436.     HFileParam    myHFPB;
  437.     OSErr        err;
  438.  
  439.     ClearBytes((Ptr)(&myHFPB), sizeof(myHFPB));
  440.  
  441.     myHFPB.ioNamePtr = name;
  442.     myHFPB.ioVRefNum = vRef;
  443.     err = PBGetFInfo((ParmBlkPtr)&myHFPB, FALSE);
  444.     *fRef = myHFPB.ioFRefNum;
  445.     return err;
  446. }
  447.  
  448.  
  449. /************************************************************************
  450.  *                                                                         *
  451.  ************************************************************************/
  452. /* utils.c */
  453.  
  454. /************************************************************************
  455.  *                                                                         *
  456.  ************************************************************************/
  457. void ClearBytes(Ptr    aPtr, LongInt nBytes)
  458. {
  459. asm    {
  460.     MOVE.L    aPtr, A0
  461.     MOVE.L    nBytes, D1
  462.     SUBQ    #1, D1
  463. @0:
  464.     CLR.B    (A0)+
  465.     DBRA    D1, @0
  466.     }
  467. }
  468.  
  469.  
  470. /************************************************************************
  471.  *                                                                         *
  472.  * Given 2 rectangles in global coords, interpolate one into the other, *
  473.  * making a zooming rectangle image on the screen.  The rectangles and    *
  474.  * the screen image are not altered.                                    *
  475.  *                                                                         *
  476.  ************************************************************************/
  477. void ZoomRect(Rect *smallRect, Rect *bigRect, integer zoomUp)
  478. {
  479. #define    Fixed        LongInt
  480. #define zoomSteps    16
  481. #define one            0x10000
  482.  
  483.     Rect            rect1, rect2, rect3, rect4;
  484.     integer            i, j;
  485.     Fixed            factor, fract,
  486.                     bt, bl, bb, br,
  487.                     st, sl, sb, sr;
  488.     GrafPtr            tmpPort;
  489.     GrafPort        myPort;
  490.  
  491.     GetPort(&tmpPort);
  492.     OpenPort(&myPort);            /* This used to be SetPort(WMgrPort)    */
  493.     CopyRgn(GrayRgn, myPort.visRgn);    /* but has been changed as per TN194    */
  494.     myPort.portRect = (*GrayRgn)->rgnBBox;
  495.     
  496.     PenMode(notPatXor);            /* This is a local pen for myPort    */
  497.     PenSize(1,1);                /* No need to restore it later        */
  498.     PenPat(gray);
  499.     
  500.     if (zoomUp)
  501.         {
  502.         rect1  = *smallRect;
  503.         factor = FixRatio(6, 5);        /* make bigger each time */
  504.         fract  = FixRatio(541, 10000);    /* 5/6 ^16 = 0.540877 */
  505.         }
  506.     else
  507.         {
  508.         rect1  = *bigRect;
  509.         factor = FixRatio(5, 6);        /* make smaller each time */
  510.         fract  = factor;                /* start full size */
  511.         }
  512.  
  513.     rect2 = rect1;
  514.     rect3 = rect1;
  515.  
  516.     sl = smallRect->left;   sl = sl << 16;    /* scale up to fixed point */
  517.     sr = smallRect->right;  sr = sr << 16;
  518.     st = smallRect->top;    st = st << 16;
  519.     sb = smallRect->bottom; sb = sb << 16;
  520.  
  521.     bl = bigRect->left;    bl = bl << 16;    /* scale up to fixed point */
  522.     br = bigRect->right;   br = br << 16;
  523.     bt = bigRect->top;     bt = bt << 16;
  524.     bb = bigRect->bottom;  bb = bb << 16;
  525.  
  526.     FrameRect(&rect1);            /* draw initial image */
  527.  
  528.     for (i = 0; i < zoomSteps; i++)
  529.         {
  530.         rect4.left   = FixRound(FixMul(fract, bl) + FixMul(one-fract, sl));
  531.         rect4.right  = FixRound(FixMul(fract, br) + FixMul(one-fract, sr));
  532.         rect4.top    = FixRound(FixMul(fract, bt) + FixMul(one-fract, st));
  533.         rect4.bottom = FixRound(FixMul(fract, bb) + FixMul(one-fract, sb));
  534.  
  535.         FrameRect(&rect4);            /* draw newest */
  536.         for (j = 0; j < 25; j++)
  537.             ;
  538.         FrameRect(&rect1);            /* erase oldest */
  539.         rect1 = rect2;
  540.         rect2 = rect3;
  541.         rect3 = rect4;
  542.         fract = FixMul(fract, factor);    /* bump interpolation fraction */
  543.         }
  544.  
  545.     FrameRect(&rect1);            /* erase final image */
  546.     FrameRect(&rect2);
  547.     FrameRect(&rect3);
  548.  
  549.     ClosePort(&myPort);
  550.     SetPort(tmpPort);
  551. }
  552.  
  553.  
  554. /************************************************************************
  555.  *                                                                         *
  556.  * InternalAlert.  Several routines require error messages to be        *
  557.  *   displayed but since they were a part of a library there was no way    *
  558.  *   of ensuring the dialog existed in the resource file.  This uses no    *
  559.  *   resource.                                                            *
  560.  *                                                                         *
  561.  ************************************************************************/
  562. static Word itms[] = {
  563.         3,                        /* number of items */
  564.  
  565.         0x0000, 0x0000,            /* place holder */
  566.         80, 208, 100, 285,        /* item rectangle */
  567.         0x0409,                    /* item type, item length (ctrl+btn, 9) */
  568.         0x4F68, 0x2046, 0x7269, 0x747A, 0x2100,
  569.                                 /* item data ( "Oh Fritz!" ) */
  570.  
  571.         0x0000, 0x0000,            /* place holder */
  572.         77, 205, 103, 288,        /* item rectangle */
  573.         0x8000,                    /* item type, item length (disabled user item, 0) */
  574.  
  575.         0x0000, 0x0000,            /* place holder */
  576.         7, 84, 67, 286,            /* item rectangle */
  577.         0x8802,                    /* item type, item length (disabled static text, 2) */
  578.         0x5E30,                    /* item data ( "^0" ) */
  579.  
  580.         0x0000, 0x0000,            /* place holder */
  581.         8, 16, 40, 48,            /* item rectangle */
  582.         0xA002,                    /* item type, item length (disabled icon, 2) */
  583.         0x0002                    /* item data ( caution icon ) */
  584.             };
  585.  
  586.  
  587. /************************************************************************/
  588. void InternalAlert()
  589. {
  590.     DialogPtr    dial;
  591.     Rect        rect;
  592.     Handle        Items = NewHandle(sizeof(itms));
  593.     integer        itmHit = 0;
  594.  
  595.     HLock(Items);
  596.     BlockMove(itms, *Items, sizeof(itms));
  597.     HUnlock(Items);
  598.  
  599.     SetRect(&rect, 40, 40, 342, 150);
  600.     dial = NewDialog(NIL, &rect, "\p",
  601.                 TRUE, dBoxProc, (WindowPtr)-1L, FALSE, 0L, Items);
  602.     SetPort(dial);
  603.  
  604.     InstallUserItem(dial, 2, (ProcPtr)DefaultFrame);
  605.  
  606.     while (itmHit != 1)
  607.         ModalDialog(NIL, &itmHit);            /* display the message     */
  608.  
  609.     DisposeDialog(dial);
  610. }
  611.